var IBInputMethod = InputMethod.extend({
	minibuf: null,
	target_obj: null,

	constructor: function()
	{
	},
	IMName: function()
	{
		return 'IBInputMethod';
	},
	GetLanguage: function()
	{
		return null;
	},
	SuggestionType: function()
	{
		return null;
	},
	onPushState: function(context)
	{
		context.minibuf = this.minibuf;
		context.target_obj = this.target_obj;
	},
	onPopState: function(context)
	{
		this.minibuf = context.minibuf;
		this.target_obj = context.target_obj;
	},
	StartMiniBuffer: function(obj,buf)
	{
		var pmb;
		pmb = this.ime.miniwin_man.RequestMiniBuffer();
	
		// store a instance
		this.minibuf = pmb;
		this.target_obj = obj;

		this.onPreStart(obj);
		// push gownfull state
		this.ime.PushState();

		pmb.Start(obj);
		pmb.SetBuffer(buf);
		this.onPostStart(pmb);
	},
	EndMiniBuffer: function(buf)
	{
		this.minibuf.End();
		// pop gownfull state
		this.ime.PopState();

		this.onComplete(this.target_obj,buf);
		// release the minibuffer object
		this.ime.miniwin_man.ReleaseMiniBuffer(this.minibuf);
		this.minibuf = null
	},
	keypress_handler: function(obj,key,m)
	{
		if(this.isKeyValid(key,m)) { // a-z A-Z
			this.StartMiniBuffer(obj,String.fromCharCode(key));
			return false;
		}
		else return true;
	},
	isKeyValid: function(key,m)
	{
		return false;
	},
	GetTitle: function()
	{
		return null;
	},
	GetInstruction: function()
	{
		return null;
	},
	onPreStart: function(obj)
	{
	},
	onPostStart: function(pmb)
	{
		var t;

		t = this.GetTitle();
		if(t) pmb.SetTitle(t);
		t = this.GetInstruction();
		if(t) pmb.SetInstruction(t);
	},
	onComplete: function(obj,buf)
	{
	}
});

var IBImgInputMethod = IBInputMethod.extend({
	// Dirty Hack for IE: we need to store the <img> object and change src etc for Internet Explorer...
	edit_mode: false,
	edit_target_img: null,
	constructor: function()
	{
	},
	IMName: function()
	{
		return 'IBImgInputMethod';
	},
	onActive: function()
	{
		this.edit_mode = false;
		this.edit_target_img = null;
	},
	onPushState: function(context)
	{
		this.base(context);
		context.edit_mode = this.edit_mode;
		context.edit_target_img = this.edit_target_img;
	},
	onPopState: function(context)
	{
		this.base(context);
		this.edit_mode = context.edit_mode;
		this.edit_target_img = context.edit_target_img;
	},
	onPostStart: function(pmb)
	{
		this.base(pmb);
		var x = this;
		pmb.SetKeyMap(13,0,function(_this) { x.EndMiniBuffer(_this.GetBuffer()); });
		pmb.SetKeyMap(13,Const.KEY_SHIFT,function(_this) { _this.AppendBuffer('\n'); });
		pmb.SetonBlurHandler(function(_this) { x.EndMiniBuffer(_this.GetBuffer()); });
	},
	GetInstruction: function()
	{
		return $GFS('Press Enter to complete');
	},
	onModify: function(obj)
	{
		var tex = obj.alt;
		this.ime.SelectInputMethod(this.im_id);
		this.StartMiniBuffer(null,decodeURI(tex));
	},
	onComplete: function(obj,buf)
	{
		if(this.edit_mode) {
			// Dirty hack: We cannot use SendHTML and replace the orginial image by using SendHTML in IE
			this.edit_target_img.alt = buf;
			this.edit_target_img.src = this.GetImageUrl(buf);

			// Dirty hack: Some bad browser will set attribute width/height....
			this.edit_target_img.width = null;
			this.edit_target_img.height = null;
			if(this.edit_target_img.removeAttribute) {
				this.edit_target_img.removeAttribute('width');
				this.edit_target_img.removeAttribute('height');
			}
			// Dirty hack: Some browser will set CSS
			this.edit_target_img.style.width = '';
			this.edit_target_img.style.height = '';

			this.edit_mode = false;
			this.edit_target_img = null;
		}
		else {
			var x = this;
			var html,adapter,id,obj,alt,src,o;
	
			adapter = GownFullObjectAdapter.GetAdapter(obj);
			if(adapter && adapter.isHTML()) {
				id = 'GownFullRichEditTemp';

				alt = encodeURI(buf);
				src = this.GetImageUrl(buf);

				html = this.GetHTMLPrefix() + '<img id="'+id+'" style="border-style:none;" alt="'+ alt + '" src="'+ src + '" />' + this.GetHTMLPostfix();
				this.ime.SendHTML(obj,html);
	
				// Dirty hack for IE: I cannot get attribute of the image from this pointer
				// we need to use event target
				adapter.SetHTMLElementEventById(id,"dblclick",function(e) { x.onModify(lib.GetEventTarget(e)); return false; });

				// Remove the ID
				o = adapter.GetHTMLElementById(id);
				o.id = '';
			}
			else {
				alt = encodeURI(buf);
				src = this.GetImageUrl(buf);

				html = this.GetHTMLPrefix() + '<img style="border-style:none;" alt="'+ alt + '" src="'+src+'" />' + this.GetHTMLPostfix();
				this.ime.SendHTML(obj,html);
			}
		}
	},
	GetHTMLPrefix: function()
	{
		return '';
	},
	GetHTMLPostfix: function()
	{
		return '';
	},
	GetImageUrl: function(buf)
	{
		return '';
	}
});
